var stripeFrameCardElements; var stripeFramePaymentClient; var stripeFrameDelaySeconds; var stripeFrame; var ourPaymentIntentId = 0; // the global variable to have an ability to match the received PI with the expected PI function GetCurrencyShortName(currency) { if (currency && currency > 0) { return currencyShortName[currency].toLowerCase() == 'nis' ? 'ILS' : currencyShortName[currency].toUpperCase(); } } function ShowStripeForm() { HideStripeElementsAndSubmitButton(); var amount = Number($('#hdnDonationAmount').val()) + Number(addiotionalSum) + Number($('#hdnDonationCoverCcAmount').val()); var currencyName = GetCurrencyShortName($('#ddlDonationCurrency :selected').val()); var valFrequency = 1; if ($("#ddlDonationFrequency").length > 0) { valFrequency = $("#ddlDonationFrequency :selected").val(); if (!valFrequency) { valFrequency = -1; } } ourPaymentIntentId++; PostStripeFrameLog('Before creating payment intent. Our id: ' + ourPaymentIntentId); var projectId = $("#hdnProjectId").val(); if (projectId === '-1') { if ($("#divProjects").is(":visible") && $("#ddlProjects option").length > 0 && $.trim($("#ddlProjects").val()) !== "") { projectId = $("#ddlProjects").val(); } } $.post( '/StripeFrame', { govid: _govId, amount: amount, currency: currencyName, recurring: valFrequency > 1, tipAmount: $('#hdnDonationTipAmount').val(), coverCcAmount: $('#hdnDonationCoverCcAmount').val(), urlfromclientside: window.location.href, urlfromserverside: $('#hdnClientUrl').val(), ourid: ourPaymentIntentId.toString(), pfpId: $("#hdnPfpId").val(), projectId: projectId } ).done(function (response) { var parsedResponse = JSON.parse(response); if (parsedResponse.result) { if(parsedResponse.ourPaymentIntentId === ourPaymentIntentId.toString()) { ShowStripeElementsAndSubmitButton(); $("#hdnPaymentAccountId").val(parsedResponse.accountId); InitStripeElements( parsedResponse.paymentClientSecret, parsedResponse.publishableKey, parsedResponse.customerId, parsedResponse.waiting_seconds, parsedResponse.paymentIntentId, parsedResponse.fees, parsedResponse.connectedAccountId ? parsedResponse.connectedAccountId : '' ); } else { PostStripeFrameLog('Received payment intent with our id: ' + parsedResponse.ourPaymentIntentId + ' but expected ' + ourPaymentIntentId); if(parsedResponse.error === 'small sum') { $("#chbCoverCc").prop("disabled", false); // enable CoverCC checkbox usedStripeFrame = false; if(confirm(_tooSmallSumForStripe)) { $("#linkEditAmount").click(); } } } } else { $('#btnDonateButton').html(ltrDonateResoureMessage); $('#btnDonateButton').removeAttr('data-toggle').removeAttr('data-target'); $('#divForCCDetails').show(); $("#chbCoverCc").prop("disabled", false); // enable CoverCC checkbox usedMeshaulm = false; usedStripeFrame = false; } }).fail(function () { ProcessResult({ sender: 'stripe-frame', type: 'error', error: 'Something went wrong.' }); }); $("#hdnCardType").val('stripeframe'); } function ProcessResult(data) { console.log(JSON.stringify(data)); if (data && data.error) { HideStripeFrameProcessingDiv(); PostStripeFrameError(data.error); $("#hdnStripeFrameError").val(data.error); alert(data.error); } else { $("#hdnStripeFramePaymentMethod").val(data.value); PostStripeFrameLog("Before call of SubmitPage()"); SubmitPage(); } } function ShowStripeFrameProcessingDiv() { $("#preparing-text").text(msgStripeFrameCompletionWaiting); $("#preparing").show(); $("#btnDonateButton").hide(); } function HideStripeFrameProcessingDiv() { $("#preparing").hide(); $("#preparing-text").text(''); $("#btnDonateButton").show(); } function HideStripeElementsAndSubmitButton() { $("#preparing").show(); // show the spinner $("#btnDonateButton").hide(); // hide submit button $("#stripePaymentForm").hide(); // hide stripe elements div $("#chbCoverCc").prop("disabled", true); // disable CoverCC checkbox } function ShowStripeElementsAndSubmitButton() { $("#preparing").hide(); // hide the spinner $("#btnDonateButton").show(); // show submit button $("#stripePaymentForm").show(); // show stripe elements div $("#chbCoverCc").prop("disabled", false); // enable CoverCC checkbox } function DismissStripeElements() { ourPaymentIntentId++; // to ignore all not completed PI requests $("#stripePaymentForm").hide(); // hide stripe elements div $("#btnDonateButton").show(); // show submit button $("#chbCoverCc").prop("disabled", false); // enable CoverCC checkbox } function PostStripeFrameError(errorObject) { console.log('****** Stripe Frame PostStripeFrameError'); try { var logUrl = "/LogError"; var message = JSON.stringify("Stripe frame error: " + errorObject); var url = window.location.href; $.ajax({ url: logUrl, type: 'POST', data: { error: message ? message : "unknown" } }); console.log('****** Error found and logged = ' + message + " url: " + url); } catch (error) { console.log(error); } } function PostStripeFrameLog(logText) { console.log('****** Stripe Frame PostStripeFrameLog'); try { var logUrl = "/LogError"; var message = JSON.stringify("Stripe frame log: " + logText); var url = window.location.href; $.ajax({ url: logUrl, type: 'POST', data: { error: message ? message : "unknown" } }); console.log('****** LogText found and logged = ' + message + " url: " + url); } catch (error) { console.log(error); } } function HideStripeElements() { $("#stripePaymentForm").hide(); } function InitStripeElements(paymentIntentKey, publishableKey, customer, delaySeconds, paymentIntentId, fee, connectedAccountId) { try { if (paymentIntentKey !== '' && publishableKey !== '') { stripeFramePaymentClient = paymentIntentKey; $("#hdnStripeFramePaymentIntentId").val(paymentIntentId); $("#hdnStripeFrameFee").val(fee); $("#hdnStripeFrameFeeCharged").val(connectedAccountId !== ''); stripeFrameDelaySeconds = delaySeconds; $("#stripePaymentForm").show(); $("#hdnStripeFrameCustomer").val(customer); if (connectedAccountId === '') { stripeFrame = Stripe( publishableKey, { maxNetworkRetries: 2, locale: stripeLanguage } ); } else { stripeFrame = Stripe( publishableKey, { maxNetworkRetries: 2, locale: stripeLanguage, stripeAccount: connectedAccountId } ); } const options = { clientSecret: paymentIntentKey }; const elements = stripeFrame.elements(options); var style = { base: { color: "#757575", fontFamily: 'Proxima-Nova, sans-serif, Arial', fontSmoothing: "antialiased", fontWeight: '300', fontSize: "1rem", "::placeholder": { color: "#757575" } }, invalid: { fontFamily: 'Proxima-Nova, sans-serif, Arial', color: "#fa755a", iconColor: "#fa755a" } }; // unmount the previous elements from DOM if exists if(stripeFrameCardElements) { stripeFrameCardElements.unmount('#payment-element'); } stripeFrameCardElements = elements.create("card", { style: style }); stripeFrameCardElements.mount('#payment-element'); } else { ProcessResult({ sender: 'stripe-frame', type: 'error', error: 'Something went wrong.' }); } } catch (e) { ProcessResult({ sender: 'stripe-frame', type: 'error', error: 'Something went wrong. ' + JSON.stringify(e) }); } } async function StripeFrameSubmitClick() { try { ShowStripeFrameProcessingDiv(); HideStripeElementsAndSubmitButton(); await StoreDonorData(); PostStripeFrameLog('Before the request to PI completion.') // Start logging every 30 seconds var logInterval = setInterval(() => { PostStripeFrameLog("Logging during PI completion process."); }, 30000); var paymentConfirmation = await stripeFrame.confirmCardPayment( stripeFramePaymentClient, { payment_method: { card: stripeFrameCardElements } }); PostStripeFrameLog("After PI completion. " + JSON.stringify(paymentConfirmation)); clearInterval(logInterval); if (paymentConfirmation.error) { ProcessResult({ sender: 'stripe-frame', type: 'error', error: paymentConfirmation.error.message }); ShowStripeElementsAndSubmitButton(); } else { await GetPaymentResults(paymentConfirmation.paymentIntent.client_secret, stripeFrame, stripeFrameDelaySeconds); } } catch (e) { PostStripeFrameError(e); } } async function GetPaymentResults(client_secret, stripeFrame, delaySeconds) { await stripeFrame.retrievePaymentIntent(client_secret).then(async ({ paymentIntent }) => { switch (paymentIntent.status) { case 'processing': case 'succeeded': ProcessResult({ sender: 'stripe-frame', type: 'payment-method', value: paymentIntent.payment_method }); break; case 'requires_payment_method': ProcessResult({ sender: 'stripe-frame', type: 'error', error: 'Payment failed. Please try another payment method.' }); break; default: ProcessResult({ sender: 'stripe-frame', type: 'error', error: 'Something went wrong.' }); break; } }); } async function StoreDonorData() { try { var coverCcAmount = Number($('#hdnDonationCoverCcAmount').val()); var amount = Number($('#hdnDonationAmount').val()) + Number(addiotionalSum) + coverCcAmount; var currencyName = GetCurrencyShortName($('#ddlDonationCurrency :selected').val()); var valFrequency = 1; if ($("#ddlDonationFrequency").length > 0) { valFrequency = $("#ddlDonationFrequency :selected").val(); if (!valFrequency) { valFrequency = -1; } } const data = { govId: _govId, paymentIntentId: document.getElementById("hdnStripeFramePaymentIntentId").value, customerId: document.getElementById("hdnStripeFrameCustomer").value, amount: amount, coverCcAmount: coverCcAmount, currency: currencyName, recurring: valFrequency > 1, email: document.getElementById('tbcontactemail').value, name: `${document.getElementById('contactfirstname').value} ${document.getElementById('contactlastname').value}` }; await fetch('/StoreDonorData', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); } catch (e) { console.error('Error storing donor data:', e); } }